/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * GUI.java
 *
 * Created on Dec 1, 2011, 7:03:51 PM
 */
package jobscheduling.gui;

import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.GroupLayout.SequentialGroup;
import javax.swing.ListModel;
import jobscheduling.model.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.swing.DefaultListModel;
import javax.swing.GroupLayout.ParallelGroup;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import jobscheduling.algorithms.bee.BeeScheduler;
import jobscheduling.algorithms.glowworm.GlowwormScheduler;
import jobscheduling.algorithms.pso.PSOScheduler;


/**
 *
 * @author bursant
 */
public class GUI extends javax.swing.JFrame {
    private static GUI _instance;
    
    public static String BEES = "Bees";
    public static String PSO = "PSO";
    public static String GW = "Glow worm";
    
    protected Map<String, String> _beeParameters = BeeScheduler.getParamsPresets();
    protected Map<String, String> _psoParameteres = PSOScheduler.getParamsPresets();
    protected Map<String, String> _glowParameters = GlowwormScheduler.getParamsPresets();
    
    protected Map<String, JTextField> _beeParamFields = new TreeMap<String, JTextField>();
    protected Map<String, JLabel> _beeParamLabels = new TreeMap<String, JLabel>();
    
    protected Map<String, JTextField> _psoParamFields = new TreeMap<String, JTextField>();
    protected Map<String, JLabel> _psoParamLabels = new TreeMap<String, JLabel>();
    
    protected Map<String, JTextField> _glowParamFields = new TreeMap<String, JTextField>();
    protected Map<String, JLabel> _glowaramLabels = new TreeMap<String, JLabel>();
    
    private MouseListener _solutionListListener;
    private MouseListener _problemListListener;
    private int _problemSelected;
    
    public synchronized void refreshInputList (){
        DefaultListModel inputModel = (DefaultListModel) outputInputList.getModel();
        inputModel.clear();
        for (Problem problem : Output.getInstance().getProblems()){
            inputModel.addElement(problem);
        }
    }
    
    public synchronized void refreshSolutionList(int index){
        DefaultListModel solutionModel = (DefaultListModel) outputSolutionList.getModel();
        DefaultListModel problemModel = (DefaultListModel) outputInputList.getModel();
        solutionModel.clear();
        Problem problem = (Problem) problemModel.get(index);  
        if (problem != null)
            for (Solution solution : Output.getInstance().getSolutions(problem)){
                solutionModel.addElement(solution);
            }
    }
    
    public static GUI getInstance(){
        return _instance;
    }
    
    /** Creates new form GUI */
    private GUI() {
        _solutionListListener = new MouseAdapter(){
            @Override
            public void mouseClicked(MouseEvent e){
                refreshInfo();
            }
        };
        _problemListListener = new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e){
                if (e.getClickCount() == 1) {
                    _problemSelected = outputInputList.locationToIndex(e.getPoint());
                    if (-1 != _problemSelected){
                        refreshSolutionList(_problemSelected);  
                    }
                }
            }
        };
        
        initComponents();
        inputList.setModel(new DefaultListModel());
        outputInputList.setModel(new DefaultListModel());
        outputSolutionList.setModel(new DefaultListModel());
        outputSolutionList.addMouseListener(_solutionListListener);
        inputList.addMouseListener(mouseListener);
        outputInputList.addMouseListener(_problemListListener);
        
        initParameters(beeParametersPanel, _beeParameters, _beeParamLabels, _beeParamFields, BeeScheduler.getParamsDescs());
        initParameters(psoParametersPanel, _psoParameteres, _psoParamLabels, _psoParamFields, PSOScheduler.getParamsDescs());
        initParameters(glowParametersPanel, _glowParameters, _glowaramLabels, _glowParamFields, GlowwormScheduler.getParamsDescs());
    }
    
    private synchronized void refreshInfo(){
        ListModel model = outputSolutionList.getModel();
        StringBuilder sb = new StringBuilder();
        for (int index : outputSolutionList.getSelectedIndices()){
            Solution solution = (Solution) model.getElementAt(index);
            Iterator<Entry<String, String>> iterator = solution.getParameters().entrySet().iterator();
            sb.append(solution.toString()).append("\n");
            sb.append("Iteration number: ");
            sb.append(solution.getBestIteration());
            sb.append("\n");
            sb.append("Best known total time: ");
            sb.append(solution.getProblem().getBestSolution());
            sb.append("\n");
            sb.append("Parameters:\n");
            while (iterator.hasNext()){
                Entry<String, String> next = iterator.next();
                sb.append(next.getKey()).append(" - ").append(next.getValue()).append("\n");
            }
            sb.append("Job order: ");
            for (int jobNumber : solution.getBestPermutation()){
                sb.append(jobNumber);
                sb.append(" ");
            }
            sb.append("\n");
            
            sb.append("\n");
        }
        outputInfo.setText(sb.toString());
    }
    
    private synchronized void initParameters(javax.swing.JPanel panel, Map<String, String> presets,
                                Map<String, JLabel> labels, Map<String, JTextField> fields,
                                Map<String, String> descs){
        /* code for bee parameters */
        Iterator<Entry<String, String>> itSS = presets.entrySet().iterator();
        List<String> paramsList = new LinkedList<String>();
        while (itSS.hasNext()){
            Entry<String, String> next = itSS.next();
            String parameter = next.getKey();
            String value = next.getValue();
            
            JLabel label = new JLabel(parameter);
            JTextField field = new JTextField(value);
            
            label.setToolTipText(descs.get(parameter));
            field.setToolTipText(descs.get(parameter));
            
            field.setMinimumSize( new Dimension(200, field.getMinimumSize().height) );
            labels.put(parameter, label);
            fields.put(parameter, field);
            paramsList.add(parameter);
        }
        
        javax.swing.GroupLayout layout = 
                new javax.swing.GroupLayout(panel);
        panel.setLayout(layout);
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
        
        Iterator<String> it = paramsList.iterator();
        SequentialGroup horizontalGroup = layout.createSequentialGroup();
        ParallelGroup labelColumn = layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING);
        ParallelGroup fieldColumn = layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING);
        while (it.hasNext())
            labelColumn.addComponent(labels.get(it.next()));
        it = paramsList.iterator();
        while (it.hasNext())
            fieldColumn.addComponent(fields.get(it.next()));
        horizontalGroup.addGroup(labelColumn).addGroup(fieldColumn);
        layout.setHorizontalGroup(horizontalGroup);
        
        SequentialGroup verticalGroup = layout.createSequentialGroup();
        it = paramsList.iterator();
        while (it.hasNext()){
            String parameter = it.next();
            javax.swing.JLabel label = labels.get(parameter);
            javax.swing.JTextField field = fields.get(parameter);
            verticalGroup.addGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(label)
                    .addComponent(field)
            );
        }
        layout.setVerticalGroup(verticalGroup);
        
        pack();
    }
    

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        tabbedPanel = new javax.swing.JTabbedPane();
        input = new javax.swing.JPanel();
        inputPane = new javax.swing.JPanel();
        inputListScrollPane = new javax.swing.JScrollPane();
        inputList = new javax.swing.JList();
        inputNew = new javax.swing.JButton();
        inputLoad = new javax.swing.JButton();
        inputRemove = new javax.swing.JButton();
        inputCompute = new javax.swing.JPanel();
        inputComputeButton = new javax.swing.JButton();
        jLabel4 = new javax.swing.JLabel();
        bee = new javax.swing.JPanel();
        beeParametersPanel = new javax.swing.JPanel();
        beeImagePanel = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        beeComputeButton = new javax.swing.JButton();
        pso = new javax.swing.JPanel();
        psoImagePanel = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        psoComputeButton = new javax.swing.JButton();
        psoParametersPanel = new javax.swing.JPanel();
        glowWorm = new javax.swing.JPanel();
        glowImagePanel = new javax.swing.JPanel();
        jLabel3 = new javax.swing.JLabel();
        glowComputeButton = new javax.swing.JButton();
        glowParametersPanel = new javax.swing.JPanel();
        output = new javax.swing.JPanel();
        outputInputPanel = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        outputInputList = new javax.swing.JList();
        outputSolutionPanel = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        outputSolutionList = new javax.swing.JList();
        outputInfoPanel = new javax.swing.JPanel();
        jScrollPane3 = new javax.swing.JScrollPane();
        outputInfo = new javax.swing.JTextArea();
        jPanel1 = new javax.swing.JPanel();
        outputCompare = new javax.swing.JButton();
        outputChart = new javax.swing.JButton();
        outputButtonsPanel = new javax.swing.JPanel();
        outputLoad = new javax.swing.JButton();
        outputSave = new javax.swing.JButton();
        outputRemove = new javax.swing.JButton();
        filechooserPanel = new javax.swing.JPanel();
        fileChooser = new javax.swing.JFileChooser();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Job Scheduler");

        inputPane.setBorder(javax.swing.BorderFactory.createTitledBorder("Input"));

        inputList.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                inputListKeyPressed(evt);
            }
        });
        inputListScrollPane.setViewportView(inputList);

        inputNew.setText("New");
        inputNew.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                inputNewActionPerformed(evt);
            }
        });

        inputLoad.setText("Load");
        inputLoad.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                inputLoadActionPerformed(evt);
            }
        });

        inputRemove.setText("Remove");
        inputRemove.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                inputRemoveActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout inputPaneLayout = new javax.swing.GroupLayout(inputPane);
        inputPane.setLayout(inputPaneLayout);
        inputPaneLayout.setHorizontalGroup(
            inputPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(inputPaneLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(inputPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(inputListScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 631, Short.MAX_VALUE)
                    .addGroup(inputPaneLayout.createSequentialGroup()
                        .addComponent(inputNew, javax.swing.GroupLayout.DEFAULT_SIZE, 206, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(inputLoad, javax.swing.GroupLayout.DEFAULT_SIZE, 207, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(inputRemove, javax.swing.GroupLayout.DEFAULT_SIZE, 206, Short.MAX_VALUE)))
                .addContainerGap())
        );
        inputPaneLayout.setVerticalGroup(
            inputPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, inputPaneLayout.createSequentialGroup()
                .addComponent(inputListScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 220, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(inputPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(inputNew)
                    .addComponent(inputLoad)
                    .addComponent(inputRemove))
                .addContainerGap())
        );

        inputCompute.setBorder(javax.swing.BorderFactory.createTitledBorder("Compute"));

        inputComputeButton.setText("Compute data with all algorithms");
        inputComputeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                inputComputeButtonActionPerformed(evt);
            }
        });

        jLabel4.setText("Create or load test data, set algorithms' parameters and compute!");

        javax.swing.GroupLayout inputComputeLayout = new javax.swing.GroupLayout(inputCompute);
        inputCompute.setLayout(inputComputeLayout);
        inputComputeLayout.setHorizontalGroup(
            inputComputeLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, inputComputeLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 399, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(27, 27, 27)
                .addComponent(inputComputeButton, javax.swing.GroupLayout.DEFAULT_SIZE, 205, Short.MAX_VALUE)
                .addContainerGap())
        );
        inputComputeLayout.setVerticalGroup(
            inputComputeLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(inputComputeLayout.createSequentialGroup()
                .addGroup(inputComputeLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(inputComputeButton)
                    .addComponent(jLabel4))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout inputLayout = new javax.swing.GroupLayout(input);
        input.setLayout(inputLayout);
        inputLayout.setHorizontalGroup(
            inputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(inputLayout.createSequentialGroup()
                .addGroup(inputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(inputLayout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addComponent(inputPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGroup(inputLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(inputCompute, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addContainerGap())
        );
        inputLayout.setVerticalGroup(
            inputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(inputLayout.createSequentialGroup()
                .addComponent(inputCompute, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(inputPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );

        tabbedPanel.addTab("Input", input);

        beeParametersPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Parameters"));

        javax.swing.GroupLayout beeParametersPanelLayout = new javax.swing.GroupLayout(beeParametersPanel);
        beeParametersPanel.setLayout(beeParametersPanelLayout);
        beeParametersPanelLayout.setHorizontalGroup(
            beeParametersPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 425, Short.MAX_VALUE)
        );
        beeParametersPanelLayout.setVerticalGroup(
            beeParametersPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 316, Short.MAX_VALUE)
        );

        jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/jobscheduling/gui/resources/bee.jpg"))); // NOI18N

        beeComputeButton.setText("Compute with Bees");
        beeComputeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                beeComputeButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout beeImagePanelLayout = new javax.swing.GroupLayout(beeImagePanel);
        beeImagePanel.setLayout(beeImagePanelLayout);
        beeImagePanelLayout.setHorizontalGroup(
            beeImagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(beeImagePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(beeImagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(beeComputeButton, javax.swing.GroupLayout.DEFAULT_SIZE, 200, Short.MAX_VALUE)
                    .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        beeImagePanelLayout.setVerticalGroup(
            beeImagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(beeImagePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(beeComputeButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 274, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(24, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout beeLayout = new javax.swing.GroupLayout(bee);
        bee.setLayout(beeLayout);
        beeLayout.setHorizontalGroup(
            beeLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, beeLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(beeParametersPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(beeImagePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        beeLayout.setVerticalGroup(
            beeLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(beeLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(beeLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(beeImagePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(beeParametersPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );

        tabbedPanel.addTab("Bee Algorithm", bee);

        jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/jobscheduling/gui/resources/swarm.jpg"))); // NOI18N

        psoComputeButton.setText("Compute with PSO");
        psoComputeButton.setName("psoComputeButton"); // NOI18N
        psoComputeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                psoComputeButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout psoImagePanelLayout = new javax.swing.GroupLayout(psoImagePanel);
        psoImagePanel.setLayout(psoImagePanelLayout);
        psoImagePanelLayout.setHorizontalGroup(
            psoImagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(psoImagePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(psoImagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(psoComputeButton, javax.swing.GroupLayout.DEFAULT_SIZE, 200, Short.MAX_VALUE)
                    .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        psoImagePanelLayout.setVerticalGroup(
            psoImagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(psoImagePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(psoComputeButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 281, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(17, Short.MAX_VALUE))
        );

        psoParametersPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Parameters"));

        javax.swing.GroupLayout psoParametersPanelLayout = new javax.swing.GroupLayout(psoParametersPanel);
        psoParametersPanel.setLayout(psoParametersPanelLayout);
        psoParametersPanelLayout.setHorizontalGroup(
            psoParametersPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 425, Short.MAX_VALUE)
        );
        psoParametersPanelLayout.setVerticalGroup(
            psoParametersPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 316, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout psoLayout = new javax.swing.GroupLayout(pso);
        pso.setLayout(psoLayout);
        psoLayout.setHorizontalGroup(
            psoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, psoLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(psoParametersPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(psoImagePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        psoLayout.setVerticalGroup(
            psoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(psoLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(psoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(psoImagePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(psoParametersPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );

        tabbedPanel.addTab("PSO Algorithm", pso);

        jLabel3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/jobscheduling/gui/resources/glow-worm.jpg"))); // NOI18N

        glowComputeButton.setText("Compute with Glow-worm");
        glowComputeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                glowComputeButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout glowImagePanelLayout = new javax.swing.GroupLayout(glowImagePanel);
        glowImagePanel.setLayout(glowImagePanelLayout);
        glowImagePanelLayout.setHorizontalGroup(
            glowImagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(glowImagePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(glowImagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(glowImagePanelLayout.createSequentialGroup()
                        .addComponent(glowComputeButton, javax.swing.GroupLayout.DEFAULT_SIZE, 192, Short.MAX_VALUE)
                        .addContainerGap())
                    .addGroup(glowImagePanelLayout.createSequentialGroup()
                        .addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGap(2, 2, 2))))
        );
        glowImagePanelLayout.setVerticalGroup(
            glowImagePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(glowImagePanelLayout.createSequentialGroup()
                .addGap(5, 5, 5)
                .addComponent(glowComputeButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 281, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(23, Short.MAX_VALUE))
        );

        glowParametersPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Parameters"));

        javax.swing.GroupLayout glowParametersPanelLayout = new javax.swing.GroupLayout(glowParametersPanel);
        glowParametersPanel.setLayout(glowParametersPanelLayout);
        glowParametersPanelLayout.setHorizontalGroup(
            glowParametersPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 429, Short.MAX_VALUE)
        );
        glowParametersPanelLayout.setVerticalGroup(
            glowParametersPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 316, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout glowWormLayout = new javax.swing.GroupLayout(glowWorm);
        glowWorm.setLayout(glowWormLayout);
        glowWormLayout.setHorizontalGroup(
            glowWormLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, glowWormLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(glowParametersPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(glowImagePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        glowWormLayout.setVerticalGroup(
            glowWormLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, glowWormLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(glowWormLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(glowParametersPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(glowImagePanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );

        tabbedPanel.addTab("Glow-worm Algorithm", glowWorm);

        outputInputPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Input"));

        jScrollPane1.setViewportView(outputInputList);

        javax.swing.GroupLayout outputInputPanelLayout = new javax.swing.GroupLayout(outputInputPanel);
        outputInputPanel.setLayout(outputInputPanelLayout);
        outputInputPanelLayout.setHorizontalGroup(
            outputInputPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(outputInputPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 134, Short.MAX_VALUE)
                .addContainerGap())
        );
        outputInputPanelLayout.setVerticalGroup(
            outputInputPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(outputInputPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 243, Short.MAX_VALUE)
                .addContainerGap())
        );

        outputSolutionPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Solution"));

        jScrollPane2.setViewportView(outputSolutionList);

        javax.swing.GroupLayout outputSolutionPanelLayout = new javax.swing.GroupLayout(outputSolutionPanel);
        outputSolutionPanel.setLayout(outputSolutionPanelLayout);
        outputSolutionPanelLayout.setHorizontalGroup(
            outputSolutionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(outputSolutionPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 133, Short.MAX_VALUE)
                .addContainerGap())
        );
        outputSolutionPanelLayout.setVerticalGroup(
            outputSolutionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(outputSolutionPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 243, Short.MAX_VALUE)
                .addContainerGap())
        );

        outputInfoPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Info"));

        outputInfo.setColumns(15);
        outputInfo.setEditable(false);
        outputInfo.setRows(5);
        jScrollPane3.setViewportView(outputInfo);

        outputCompare.setText("Compare");
        outputCompare.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                outputCompareActionPerformed(evt);
            }
        });

        outputChart.setText("Chart");
        outputChart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                outputChartActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(outputCompare, javax.swing.GroupLayout.DEFAULT_SIZE, 135, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(outputChart, javax.swing.GroupLayout.DEFAULT_SIZE, 127, Short.MAX_VALUE)
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(outputCompare)
                    .addComponent(outputChart))
                .addContainerGap())
        );

        javax.swing.GroupLayout outputInfoPanelLayout = new javax.swing.GroupLayout(outputInfoPanel);
        outputInfoPanel.setLayout(outputInfoPanelLayout);
        outputInfoPanelLayout.setHorizontalGroup(
            outputInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, outputInfoPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(outputInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPane3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 288, Short.MAX_VALUE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        outputInfoPanelLayout.setVerticalGroup(
            outputInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, outputInfoPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 243, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        outputLoad.setText("Load");
        outputLoad.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                outputLoadActionPerformed(evt);
            }
        });

        outputSave.setText("Save");
        outputSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                outputSaveActionPerformed(evt);
            }
        });

        outputRemove.setText("Remove");
        outputRemove.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                outputRemoveActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout outputButtonsPanelLayout = new javax.swing.GroupLayout(outputButtonsPanel);
        outputButtonsPanel.setLayout(outputButtonsPanelLayout);
        outputButtonsPanelLayout.setHorizontalGroup(
            outputButtonsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(outputButtonsPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(outputLoad, javax.swing.GroupLayout.DEFAULT_SIZE, 100, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(outputSave, javax.swing.GroupLayout.DEFAULT_SIZE, 100, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(outputRemove, javax.swing.GroupLayout.DEFAULT_SIZE, 105, Short.MAX_VALUE)
                .addContainerGap())
        );
        outputButtonsPanelLayout.setVerticalGroup(
            outputButtonsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(outputButtonsPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(outputButtonsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(outputLoad)
                    .addComponent(outputSave)
                    .addComponent(outputRemove))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout outputLayout = new javax.swing.GroupLayout(output);
        output.setLayout(outputLayout);
        outputLayout.setHorizontalGroup(
            outputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(outputLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(outputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(outputLayout.createSequentialGroup()
                        .addComponent(outputInputPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(outputSolutionPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addComponent(outputButtonsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(outputInfoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
        outputLayout.setVerticalGroup(
            outputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, outputLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(outputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(outputInfoPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(outputLayout.createSequentialGroup()
                        .addGroup(outputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(outputSolutionPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(outputInputPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(outputButtonsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );

        tabbedPanel.addTab("Output", output);

        filechooserPanel.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));

        fileChooser.setFileFilter(new FileFilter());

        javax.swing.GroupLayout filechooserPanelLayout = new javax.swing.GroupLayout(filechooserPanel);
        filechooserPanel.setLayout(filechooserPanelLayout);
        filechooserPanelLayout.setHorizontalGroup(
            filechooserPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(filechooserPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(fileChooser, javax.swing.GroupLayout.PREFERRED_SIZE, 242, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        filechooserPanelLayout.setVerticalGroup(
            filechooserPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(filechooserPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(fileChooser, javax.swing.GroupLayout.PREFERRED_SIZE, 149, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(tabbedPanel)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(tabbedPanel)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

MouseListener mouseListener = new MouseAdapter() {
    @Override
    public void mouseClicked(MouseEvent e){
        if (e.getClickCount() != 2)
            return;
        
        final int index = inputList.locationToIndex(e.getPoint());
        if(index  < 0)
            return;
        refreshParameters();
        java.awt.EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            for (int index : inputList.getSelectedIndices()){
                ComputingPanel computingPanel = 
                    new ComputingPanel(
                        (Problem)inputList.getModel().getElementAt(index), 
                        new TreeMap<String,String>(_beeParameters),
                        new TreeMap<String,String>(_psoParameteres),
                        new TreeMap<String,String>(_glowParameters),
                        0 //all checkBoxes selected
                    );
                computingPanel.setVisible(true);
            }
        }
    });   
    }
};    
    
private void inputNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_inputNewActionPerformed
    Problem newProblem = new Problem();
    ((DefaultListModel)inputList.getModel()).addElement(newProblem);
}//GEN-LAST:event_inputNewActionPerformed

private void inputLoadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_inputLoadActionPerformed
    fileChooser.setCurrentDirectory(new File("input"));
    int returnVal = fileChooser.showOpenDialog(this);
    if (returnVal == JFileChooser.APPROVE_OPTION) {
        File file = fileChooser.getSelectedFile();
        int thisMany = 0;
        try {
            BufferedReader br = new BufferedReader(new FileReader( file.getAbsolutePath()));
            while (true){
                br.readLine();    
                Problem newProblem = new Problem(br, file.getName());
                ListModel model = inputList.getModel();
                int i = 0;
                for (i = 0; i < model.getSize(); ++i){
                    Problem problem = (Problem)model.getElementAt(i);
                    if (problem.equals(newProblem))
                        break;
                }
                if (i == model.getSize()){
                    ((DefaultListModel)inputList.getModel()).addElement(newProblem);
                    thisMany += 1;
                }
            }
        } catch (Exception ex) { }
        System.out.println("Loaded new " + thisMany + "problems\n");
    }
}//GEN-LAST:event_inputLoadActionPerformed

private void inputRemoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_inputRemoveActionPerformed
    for(int index = 0; index < inputList.getModel().getSize(); index++){
        if(inputList.isSelectedIndex(index)){
            ((DefaultListModel)inputList.getModel()).remove(index); 
            index--;
        }
    }
}//GEN-LAST:event_inputRemoveActionPerformed

private void inputComputeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_inputComputeButtonActionPerformed
    if(inputList.getModel().getSize() != 0)
        openComputingWindow(0);
    else
        openFileChooser();
}//GEN-LAST:event_inputComputeButtonActionPerformed

/**
 * 
 * @param selectedCheckboxes checkboxes selected by default: 1 - Bee, 2-PSO, 3-Glow, 0-All
 */
protected void openComputingWindow(final int selectedCheckboxes){
    refreshParameters();
    if(inputList.getSelectedIndex() == -1){
        JOptionPane.showMessageDialog(this, "select some input data.", "Information", JOptionPane.PLAIN_MESSAGE);
        return;
    }
    java.awt.EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            for (int index : inputList.getSelectedIndices()){
                ComputingPanel computingPanel = 
                    new ComputingPanel(
                        (Problem)inputList.getModel().getElementAt(index), 
                        new TreeMap<String,String>(_beeParameters),
                        new TreeMap<String,String>(_psoParameteres),
                        new TreeMap<String,String>(_glowParameters),
                        selectedCheckboxes
                    );
                computingPanel.setVisible(true);
            }
        }
    }); 
}

private void outputRemoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_outputRemoveActionPerformed
    int[] selected = outputSolutionList.getSelectedIndices();
    if (selected != null && selected.length != 0){
        Problem problem = (Problem)outputInputList.getModel().getElementAt(
            outputInputList.getSelectedIndex()
        );
        for (int index : outputSolutionList.getSelectedIndices()){
            Output.getInstance().removeSolution(
                (Solution)outputSolutionList.getModel().getElementAt(index), 
                problem
            );
        }
        refreshSolutionList(outputInputList.getSelectedIndex());
    } else {
        selected = outputInputList.getSelectedIndices();
        for (int index : selected){
            Output.getInstance().removeProblem(
                (Problem)outputInputList.getModel().getElementAt(index)
            );
        }
        refreshInputList();
        ((DefaultListModel)outputSolutionList.getModel()).clear();
    }
    refreshInfo();
}//GEN-LAST:event_outputRemoveActionPerformed

private void outputChartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_outputChartActionPerformed
    ListModel model = outputSolutionList.getModel();
    for (int index : outputSolutionList.getSelectedIndices()){
        Solution solution = (Solution) model.getElementAt(index);
        Problem bestPerm = solution.getBestPerm();
        GanttChart ganttChart = new GanttChart(bestPerm, solution.getBestPermutation());
    }
}//GEN-LAST:event_outputChartActionPerformed

private void outputCompareActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_outputCompareActionPerformed
    List<Solution> selectedSolutions = new LinkedList<Solution>();
    for (int index : outputSolutionList.getSelectedIndices()){
        selectedSolutions.add((Solution)outputSolutionList.getModel().getElementAt(index));
    }
    ComparingChart comparingChart = new ComparingChart(selectedSolutions);
}//GEN-LAST:event_outputCompareActionPerformed

private void inputListKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_inputListKeyPressed
    if(evt.getKeyCode() != KeyEvent.VK_ENTER)
        return;
    final int[] indices = inputList.getSelectedIndices();
    for(int i = 0; i < indices.length; i++)
    {
        final int currentIndex = i;
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                Editor e = new Editor(inputList, indices[currentIndex]);
                e.setVisible(true);
            }
        });
    }
}//GEN-LAST:event_inputListKeyPressed

private void outputSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_outputSaveActionPerformed
    fileChooser.setCurrentDirectory(new File("output"));
    Problem problem = (Problem) outputInputList.getSelectedValue();
    fileChooser.setSelectedFile(new File(problem.getName()+ ".dat"));
    int retVal = fileChooser.showDialog(this, "Save");
    if(retVal == JFileChooser.APPROVE_OPTION){
        SolutionDTO dto = new SolutionDTO(problem, Output.getInstance().getSolutions(problem));
        FileOutputStream fout;
        try {
            fout = new FileOutputStream(fileChooser.getSelectedFile().getAbsolutePath());
            ObjectOutputStream oos;  
            oos = new ObjectOutputStream(fout); 
            oos.writeObject(dto);
            oos.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}//GEN-LAST:event_outputSaveActionPerformed

private void outputLoadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_outputLoadActionPerformed
    openFileChooser();
}//GEN-LAST:event_outputLoadActionPerformed

private void openFileChooser(){
    fileChooser.setCurrentDirectory(new File("input"));
    int returnVal = fileChooser.showOpenDialog(this);
    if (returnVal == JFileChooser.APPROVE_OPTION) {
        File file = fileChooser.getSelectedFile();
        int thisMany = 0;
        try {
            BufferedReader br = new BufferedReader(new FileReader( file.getAbsolutePath()));
            while (true){
                br.readLine();    
                Problem newProblem = new Problem(br, file.getName());
                ListModel model = inputList.getModel();
                int i = 0;
                for (i = 0; i < model.getSize(); ++i){
                    Problem problem = (Problem)model.getElementAt(i);
                    if (problem.equals(newProblem))
                        break;
                }
                if (i == model.getSize()){
                    ((DefaultListModel)inputList.getModel()).addElement(newProblem);
                    thisMany += 1;
                }
            }
        } catch (Exception ex) { }
        System.out.println("Loaded new " + thisMany + "problems\n");
        inputList.setSelectedIndex(0);
    }
}

private void beeComputeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_beeComputeButtonActionPerformed
    openComputingWindow(1);
}//GEN-LAST:event_beeComputeButtonActionPerformed

private void psoComputeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_psoComputeButtonActionPerformed
    openComputingWindow(2);
}//GEN-LAST:event_psoComputeButtonActionPerformed

private void glowComputeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_glowComputeButtonActionPerformed
    openComputingWindow(3);
}//GEN-LAST:event_glowComputeButtonActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            
            @Override
            public void run() {
                _instance = new GUI();
                _instance.setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel bee;
    private javax.swing.JButton beeComputeButton;
    private javax.swing.JPanel beeImagePanel;
    private javax.swing.JPanel beeParametersPanel;
    private javax.swing.JFileChooser fileChooser;
    private javax.swing.JPanel filechooserPanel;
    private javax.swing.JButton glowComputeButton;
    private javax.swing.JPanel glowImagePanel;
    private javax.swing.JPanel glowParametersPanel;
    private javax.swing.JPanel glowWorm;
    private javax.swing.JPanel input;
    private javax.swing.JPanel inputCompute;
    private javax.swing.JButton inputComputeButton;
    private javax.swing.JList inputList;
    private javax.swing.JScrollPane inputListScrollPane;
    private javax.swing.JButton inputLoad;
    private javax.swing.JButton inputNew;
    private javax.swing.JPanel inputPane;
    private javax.swing.JButton inputRemove;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JPanel output;
    private javax.swing.JPanel outputButtonsPanel;
    private javax.swing.JButton outputChart;
    private javax.swing.JButton outputCompare;
    private javax.swing.JTextArea outputInfo;
    private javax.swing.JPanel outputInfoPanel;
    private javax.swing.JList outputInputList;
    private javax.swing.JPanel outputInputPanel;
    private javax.swing.JButton outputLoad;
    private javax.swing.JButton outputRemove;
    private javax.swing.JButton outputSave;
    private javax.swing.JList outputSolutionList;
    private javax.swing.JPanel outputSolutionPanel;
    private javax.swing.JPanel pso;
    private javax.swing.JButton psoComputeButton;
    private javax.swing.JPanel psoImagePanel;
    private javax.swing.JPanel psoParametersPanel;
    private javax.swing.JTabbedPane tabbedPanel;
    // End of variables declaration//GEN-END:variables

    private synchronized void refreshParameters() {
        Iterator<Entry<String, JTextField>> iterator = _beeParamFields.entrySet().iterator();
        while (iterator.hasNext()){
            Entry<String, JTextField> next = iterator.next();
            String key = next.getKey();
            JTextField value = next.getValue();
            _beeParameters.put(key, value.getText());
        }
        
        iterator = _psoParamFields.entrySet().iterator();
        while (iterator.hasNext()){
            Entry<String, JTextField> next = iterator.next();
            String key = next.getKey();
            JTextField value = next.getValue();
            _psoParameteres.put(key, value.getText());
        }
        
        iterator = _glowParamFields.entrySet().iterator();
        while (iterator.hasNext()){
            Entry<String, JTextField> next = iterator.next();
            _glowParameters.put(next.getKey(), next.getValue().getText());
        }
    }
}
